package dk.wifiathome;

import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import dk.wifiathome.wifiathomeFileHandler;

public class wifiathome extends Activity implements OnClickListener,
		LocationListener {
	/** Called when the activity is first created. */

	public boolean Debug = false; // Global debug flag enabled through the main
	static final double targetRadiusGps = 0.05; // 50 m
	static final double targetRadiusCell = 1.500; // 1500 m

	static final int DIALOG_SETTINGS_ID = 0;
	static final int DIALOG_EXIT_ID = 1;

	String wifiSpotName = "";
	ProgressDialog MyDialog;

	Location SavedGpsLocation = null;
	Location SavedCellLocation = null;
	LocationManager lmc = null;
	LocationManager lm = null;
	WifiManager wm = null;

	Intent positionListGui = null;

	boolean gpsEnabled = false;
	boolean requestGpsUpdateBeforeAdd = false;
	wifiathomeFileHandler debugFileHandler;
	wifiathomeFileHandler listFileHandler;

	static String LogFileLocation = "/sdcard/Android/data/dk.wifiathome/files/log.txt";
	static String ListFileLocation = "/sdcard/Android/data/dk.wifiathome/files/list.xml";

	// Timer LOL
	private Handler mHandler = new Handler();
	int TimeInterval = 60;// * 5; // 60 sec
	long mStartTime = 0; // 15 [s]
	TextView TempTextview;
	int tick = 0;
	int tick2 = 0;

	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);
		return true;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		positionListGui = new Intent(wifiathome.this, positionListGui.class);

		// Add buttons to view listener
		Button AddPos = (Button) findViewById(R.id.AddPosition);
		AddPos.setOnClickListener(this);

		Button ListPos = (Button) findViewById(R.id.ListPositions);
		ListPos.setOnClickListener(this);

		Button GpsInfo = (Button) findViewById(R.id.GpsInfo);
		GpsInfo.setOnClickListener(this);

		Button CellInfo = (Button) findViewById(R.id.CellInfo);
		CellInfo.setOnClickListener(this);

		lmc = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		lmc
				.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
						this);

		wm = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

		// / We need to look in the configuration here to see what to enable.
		// /// Timer specific
		TempTextview = (TextView) findViewById(R.id.mTimeLabel);

		mStartTime = System.currentTimeMillis();
		mHandler.removeCallbacks(mUpdateTimeTask);

		// localFileHandler = new wifiathomeFileHandler(this, LogFileLocation);

		// if (Configuration.useGps)
		enableGps();
	}

	private double calcDistanceBetweenPoints(double latitude, double longitude,
			double sLatitude, double sLongitude) {
		int R = 6371; // radius of earth in km
		double dLat = Math.toRadians(latitude - sLatitude);
		double dLong = Math.toRadians(longitude - sLongitude);

		double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
				+ Math.cos(Math.toRadians(sLatitude))
				* Math.cos(Math.toRadians(latitude)) * Math.sin(dLong / 2)
				* Math.sin(dLong / 2);
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

		double distance = R * c; // in km

		Toast.makeText(this, "distance is " + distance, Toast.LENGTH_LONG)
				.show();

		return distance;
	}
	
/*	public void  onCancel  (DialogInterface dialog){ // THIS DOESN'T WORK!!!!!!?!??!?!?!?!?!?!?!?!?
		Toast.makeText(this, "STOP!", Toast.LENGTH_LONG)
		.show();
		requestGpsUpdateBeforeAdd = false;
		lm.removeUpdates(this);
	}*/

	public void addPositionToList() {
		if (requestGpsUpdateBeforeAdd == false) {

			final AlertDialog.Builder alert = new AlertDialog.Builder(this);
			final EditText input = new EditText(this);
			alert.setView(input);
			alert.setMessage("Please enter location name");
			alert.setPositiveButton("Ok",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
							wifiSpotName = input.getText().toString().trim();

							enableGps();
							requestGpsUpdateBeforeAdd = true;
														
							MyDialog = ProgressDialog.show( wifiathome.this, " " , " Getting location fix ... ", true);	
							MyDialog.setCanceledOnTouchOutside(true);
							MyDialog.setOnCancelListener(new OnCancelListener() {
				                @Override
				                public void onCancel(DialogInterface dialog) {
				                    Toast.makeText(wifiathome.this, "canceled", Toast.LENGTH_SHORT).show();
				            		requestGpsUpdateBeforeAdd = false;
				            		wifiathome.this.lm.removeUpdates(wifiathome.this);
				                }
				            });
							
						}
					});

			alert.setNegativeButton("Cancel",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
							dialog.cancel();
							return;
						}
					});
			alert.show();

		} else {
			positionList app = (positionList) getApplication();
			app.AddPositionListEntry(wifiSpotName, SavedCellLocation,
					SavedGpsLocation);
			MyDialog.dismiss();
			
			if (!wm.isWifiEnabled())
				wm.setWifiEnabled(true);
			
			requestGpsUpdateBeforeAdd = false;
		}
	}

	public void enableGps() {
		/*
		 * Get the gps coordinate Enable the GPS if disabled get get coordinate
		 * and then disable it again
		 */
		// / if () // Gps not turned on, turn it on.

		lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
		gpsEnabled = true;

		// make sure the timer is not started before needed!
		mHandler.removeCallbacks(mUpdateTimeTask);
	}

	/*
	 * getGpsInformation will get the information from the return call from the
	 * GPS device it will then calculate the distance betweehttp://www.google.com/search?client=ubuntu&channel=fs&q=my+possition&ie=utf-8&oe=utf-8#hl=en&&sa=X&ei=ndR0TJDEJoXGsgbjwoCDDw&ved=0CBQQvwUoAQ&q=my+position&spell=1&fp=93c3c78db929eee0n the new location
	 * and the list of known locations if one of these locations is within the
	 * specified distance the wifi is turned on.
	 */
	public void getGpsInformation(Location location) {
		if (location != null && gpsEnabled) {

			if (location.getAccuracy() < 15) {
				Toast.makeText(this, "getAccuracy = " + location.getAccuracy(),
						Toast.LENGTH_LONG).show();
				SavedGpsLocation = location;
				lm.removeUpdates(this);
				gpsEnabled = false;

				if (requestGpsUpdateBeforeAdd) {
					addPositionToList();
					// start timer
					mHandler.postDelayed(mUpdateTimeTask, TimeInterval * 1000);
					return;
				}
				/*
				 * Date date = new Date(); String minutes; int intMinutes =
				 * date.getMinutes(); if (intMinutes < 10) minutes = "0"+
				 * intMinutes; else minutes = ""+ intMinutes;
				 * 
				 * String seconds; int intSeconds = date.getSeconds(); if
				 * (intSeconds < 10) seconds = "0" + intSeconds; else seconds =
				 * "" + intSeconds;
				 * 
				 * String input = "["+ date.getHours()+ ":"+ minutes+ ":"+
				 * seconds+"]" + "Gps: lat: " + SavedLocation.getLatitude() +
				 * " long:" + SavedLocation.getLongitude();
				 * localFileHandler.writeToFile(input);
				 */
				// get hold of the application container
				positionList app = (positionList) getApplication();
				ArrayList<listData> locationList = app.getPositionArrayList();
				// Run through the list of saved locations.
				boolean insideTagetRadius = false;
				for (int i = 0; i < locationList.size(); i++) {
					// Calculate the distance to target destination
					double wifiSpotGpsInfoLat = locationList.get(i)
							.getWifiSpotGpsInfoLat();
					double wifiSpotGpsInfoLong = locationList.get(i)
							.getWifiSpotGpsInfoLong();

					if (SavedGpsLocation != null && wifiSpotGpsInfoLat != -1
							&& wifiSpotGpsInfoLong != -1) {
						if (targetRadiusGps >= (calcDistanceBetweenPoints(
								SavedGpsLocation.getLatitude(),
								SavedGpsLocation.getLongitude(),
								wifiSpotGpsInfoLat, wifiSpotGpsInfoLong))) {
							insideTagetRadius = true;
							break;
						}
					}
				}

				if (insideTagetRadius && !wm.isWifiEnabled()) {
					wm.setWifiEnabled(true);
					Toast.makeText(this, "Wifi Enabled", Toast.LENGTH_LONG)
							.show();
				} else {
					if (!insideTagetRadius && wm.isWifiEnabled())
						wm.setWifiEnabled(false);
				}
				// start timer
				mHandler.postDelayed(mUpdateTimeTask, TimeInterval * 1000);
			}
		} else
			Toast
					.makeText(this, "Location = Not Accessable",
							Toast.LENGTH_LONG).show();
	}

	public void getCellInformation(Location location) {
		if (location != null && gpsEnabled) {
			SavedCellLocation = location;
			
			Toast.makeText(
					this,
					"Cell Accuracy " + location.getAccuracy(),
					Toast.LENGTH_LONG).show();

			/*
			 * Date date = new Date(); String minutes; int intMinutes =
			 * date.getMinutes(); if (intMinutes < 10) minutes = "0"+
			 * intMinutes; else minutes = ""+ intMinutes;
			 * 
			 * String seconds; int intSeconds = date.getSeconds(); if
			 * (intSeconds < 10) seconds = "0" + intSeconds; else seconds = "" +
			 * intSeconds;
			 * 
			 * String input = "["+ date.getHours()+ ":"+ minutes+ ":"+
			 * seconds+"]" + "Cell: lat: " + SavedCellLocation.getLatitude() +
			 * " long:" + SavedCellLocation.getLongitude();
			 * localFileHandler.writeToFile(input);
			 */

			// get hold of the application container

/*			positionList app = (positionList) getApplication();
			ArrayList<listData> locationList = app.getPositionArrayList(); //
			// Run through the list of saved locations.
			boolean insideTagetRadius = false;
			for (int i = 0; i < locationList.size(); i++) {
				// Calculate the distance to target destination
				double wifiSpotCellInfoLat = locationList.get(i)
						.getWifiSpotCellInfoLat();
				double wifiSpotCellInfoLong = locationList.get(i)
						.getWifiSpotCellInfoLong();

				if (SavedGpsLocation != null && wifiSpotCellInfoLat != -1
						&& wifiSpotCellInfoLong != -1) {
					if (targetRadiusGps >= (calcDistanceBetweenPoints(
							SavedGpsLocation.getLatitude(), SavedGpsLocation
									.getLongitude(), wifiSpotCellInfoLat,
							wifiSpotCellInfoLong))) {
						insideTagetRadius = true;
						break;
					}
				}
			}

/ *			if (insideTagetRadius) {
				if (!wm.isWifiEnabled())
//					wm.setWifiEnabled(true);
				Toast.makeText(this, "Wifi Enabled", Toast.LENGTH_LONG).show();
			} else {
				if (!insideTagetRadius && wm.isWifiEnabled())
//					wm.setWifiEnabled(false);
	*/		//	Toast.makeText(this, "Wifi Disabled", Toast.LENGTH_LONG).show();
			tick2++;
			TempTextview.setText("Gps Updated " + tick + " times \n cell updated " + tick2 + " times :-D ");
				
		//	}

		} else
			Toast
					.makeText(this, "Location = Not Accessable",
							Toast.LENGTH_LONG).show();
	}

	public void showGpsInfo() {
		if (SavedGpsLocation != null) {
			Toast.makeText(
					this,
					"Location (lat / long) = " + SavedGpsLocation.getLatitude()
							+ " / " + SavedGpsLocation.getLongitude()
							+ "Gps Updated " + tick + " times",
					Toast.LENGTH_LONG).show();
		} else
			Toast.makeText(this, "Location = N/A", Toast.LENGTH_LONG).show();
	}

	public void showCellInfo() {
		if (SavedCellLocation != null) {
			Toast.makeText(
					this,
					"Location (lat / long) = "
							+ SavedCellLocation.getLatitude() + "/"
							+ SavedCellLocation.getLongitude(),
					Toast.LENGTH_LONG).show();
		} else
			Toast.makeText(this, "CellLocation = N/A", Toast.LENGTH_LONG)
					.show();
	}

	/* This method is called when use position will get changed */
	public void onLocationChanged(Location location) {
		if (location.getProvider().equals(LocationManager.GPS_PROVIDER))
			getGpsInformation(location);
		else if (location.getProvider()
				.equals(LocationManager.NETWORK_PROVIDER))
			getCellInformation(location);
		else
			Toast.makeText(this, "unknown provider", Toast.LENGTH_LONG);
	}

	public void onProviderDisabled(String provider) {
		Toast.makeText(this, "Provider disabled", Toast.LENGTH_LONG).show();
		// enable the Provider
		if (provider.equals(LocationManager.GPS_PROVIDER)) {
			// / Enable the Gps Provider
			Toast
					.makeText(this, "Enabling the Gps Provider",
							Toast.LENGTH_LONG).show();

		}// else if (provider == )
	}

	public void onProviderEnabled(String provider) {
	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.settings: {
			Intent i = new Intent(wifiathome.this, settings.class);
			startActivity(i);

			return true;
		}
		case R.id.exit: {
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Are you sure you want to exit?").setCancelable(
					false).setPositiveButton("Yes",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							// localFileHandler.closeLogFile();
							System.exit(0);
						}
					}).setNegativeButton("No",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							dialog.cancel();
						}
					});
			builder.show();

			return true;
		}
		case R.id.debug: {
			if (Debug) {
				Toast.makeText(this, "Debug has now been disabled",
						Toast.LENGTH_LONG);
				Debug = false;
			} else {
				Toast.makeText(this, "Debug has now been enabled",
						Toast.LENGTH_LONG);
				Debug = true;
			}
			return true;
		}
		case R.id.about: {
			// TODO This is only for the showing of the distance between the two
			// points!
			if (SavedCellLocation != null && SavedGpsLocation != null) {
				calcDistanceBetweenPoints(SavedGpsLocation.getLatitude(),
						SavedGpsLocation.getLongitude(), SavedCellLocation
								.getLatitude(), SavedCellLocation
								.getLongitude());
			}
			return true;
		}
		default:
			return false;
		}
	}

	@Override
	public void onClick(View arg0) {
		switch (arg0.getId()) {
		case R.id.AddPosition: {
			this.addPositionToList();
			return;
		}
		case R.id.ListPositions: {

			startActivity(positionListGui);
			return;

			// TESTING ZE WIFI!!! PLEAZE REMOVE VEN NO USE NO MORE!!! ;-)
			/*
			 * if (!wm.isWifiEnabled()) wm.setWifiEnabled(true); else
			 * wm.setWifiEnabled(false);
			 */
		}
		case R.id.GpsInfo: {
			this.showGpsInfo();
			return;
		}
		case R.id.CellInfo: {
			this.showCellInfo();
			return;
		}
		default:
			// do nothing
			return;
		}

	}

	/*****
	 * Embedded timer class that periodically will invoke the gathering of GPS
	 * info
	 * 
	 * Used below site for inspiration:
	 * http://developer.android.com/resources/articles/timed-ui-updates.html
	 */

	private Runnable mUpdateTimeTask = new Runnable() {
		public void run() {
			tick++;
			TempTextview.setText("Gps Updated " + tick + " times \n cell updated " + tick2 + " times :-D ");
			enableGps();
		}
	};

}
